package com.xbongbong.paas.service.dynamic.help;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.help.dynamic.BusinessDynamicHelp;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.StageTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.LinkInfoPojo;
import com.xbongbong.paas.field.LinkListPojo;
import com.xbongbong.paas.help.FormDataHelp;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.help.ProGetHelp;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.dto.AnalysisDataDTO;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.service.dynamic.crm.strategy.DynamicStrategyFactory;
import com.xbongbong.paas.service.dynamic.crm.strategy.PushNotifyDynamicStrategy;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.TitleUtil;
import com.xbongbong.parent.interfaces.DynamicStrategy;
import com.xbongbong.pro.businesstage.pojo.dto.CommonJumpDTO;
import com.xbongbong.pro.customercommunicate.pojo.dto.LinkDataDynamicAddDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicDeleteLinkData;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicLinkDataStageJump;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicPushNotifyAddDTO;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.domain.entity.competitor.CompetitorEntity;
import com.xbongbong.saas.domain.entity.ext.OpportunityEntityExt;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CompetitorEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.model.CompetitorModel;
import com.xbongbong.saas.model.OpportunityModel;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.model.UserModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author: yingjf
 * @date: 2022/5/23 14:23
 * @description:
 */
@Slf4j
@Component
public class DynamicHelp extends BusinessDynamicHelp {
    @Resource
    private DynamicStrategyFactory dynamicStrategyFactory;
    @Resource
    private FormDataHelp formDataHelp;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private UserModel userModel;
    @Resource
    private CompetitorModel competitorModel;
    @Resource
    private OpportunityModel opportunityModel;
    @Resource
    private ProGetHelp proGetHelp;




    @Async("dynamicThreadPool")
    public  void deleteLinkData(String corpid, Integer saasMark, Integer businessType, List<Long> dataIdList,
                                String userId, String userName, Long formId,
                                List<PaasFormDataEntityExt>
                                            paasFormDataEntityExtList,
                                Map<String, FieldAttrEntity> explainMap, AnalysisDataDTO analysisDataDTO)throws XbbException{

        if(CollectionUtils.isEmpty(paasFormDataEntityExtList)){
            paasFormDataEntityExtList = formDataHelp.getByDataIdList(dataIdList,businessType,saasMark,formId,corpid);
        }
        if(explainMap==null){
            PaasFormExplainEntity paasFormExplainEntity = proFormHelp.getExplainEntity(corpid, formId, businessType);
            explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
        }
        Set<String> set = new HashSet<>();

        Set<Long> formIds =  new HashSet<>();
        for(PaasFormDataEntityExt paasFormDataEntityExt: paasFormDataEntityExtList) {
            explainMap.forEach((attr, fieldAttrEntity) -> {
                Integer fieldType = fieldAttrEntity.getFieldType();
                if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA.getType())) {
                    LinkInfoPojo linkInfo = fieldAttrEntity.getLinkInfo();
                    Integer linkBusinessType = linkInfo.getLinkBusinessType();
                    if(!SHOW_DYNAMIC_BUSINESSTYPE_LIST.contains(linkBusinessType)){
                        return;
                    }
                    formIds.add(linkInfo.getLinkFormId());
                }
            });
        }
        Map<String, Object> param = new HashMap<>(2 << 1);
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        param.put(ParameterConstant.ID_IN, formIds);
        List<PaasFormEntity> paasFormEntityList = paasFormModel.findEntity(param);

        Map<Long,Set<String>> associationMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        paasFormEntityList.forEach(item->{
            PaasFormEntity paasFormEntity = item;
            List<LinkListPojo> associationList = JSONArray.parseArray(paasFormEntity.getAssociationList(), LinkListPojo.class);
            if (Objects.isNull(associationList)) {
                associationList = new ArrayList<>();
            }
            Set<String> associationSet = new HashSet<>();

            associationList.forEach(temp->{
                Integer linkSaasMark = temp.getLinkSaasMark();
                Integer linkBusinessType = temp.getLinkBusinessType();
                if (Objects.equals(temp.getEnable(), 1)) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(linkSaasMark).append(linkBusinessType).append(formId);
                    associationSet.add(sb.toString());
                }
            });
            associationMap.put(item.getId(),associationSet);
        });
        Map<Integer,List<DynamicDeleteLinkData>> dataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formId,corpid);
        for(PaasFormDataEntityExt paasFormDataEntityExt: paasFormDataEntityExtList){
            JSONObject data = paasFormDataEntityExt.getData();
            Long dataId = paasFormDataEntityExt.getDataId();
            Map<String, FieldAttrEntity> finalExplainMap = explainMap;
            explainMap.forEach((attr, fieldAttrEntity)->{
                Integer fieldType = fieldAttrEntity.getFieldType();
                if(Objects.equals(fieldType, FieldTypeEnum.LINK_DATA.getType())){
                    LinkInfoPojo linkInfo = fieldAttrEntity.getLinkInfo();
                    Integer linkSaasMark = linkInfo.getLinkSaasMark();
                    Integer linkBusinessType = linkInfo.getLinkBusinessType();
                    Long linkFormId = linkInfo.getLinkFormId();
                    if(!SHOW_DYNAMIC_BUSINESSTYPE_LIST.contains(linkBusinessType)){
                        return;
                    }
                    StringBuilder key = new StringBuilder();
                    Long parentDataId = data.getLong(attr);
                     if (Objects.equals(parentDataId, 0L) || Objects.isNull(parentDataId)) {
                         return;
                     }
                    key.append(linkSaasMark).append(linkBusinessType).append(parentDataId).append(dataId);

                    StringBuilder sb = new StringBuilder();
                    sb.append(saasMark).append(businessType).append(paasFormDataEntityExt.getFormId());

                    Set<String> tempSet = associationMap.get(linkFormId);
                    if(!tempSet.contains(sb.toString())){
                        return;
                    }
                    if(set.contains(key.toString())){
                        return;
                    }else {
                        set.add(key.toString());
                    }

                    DynamicDeleteLinkData dynamicDeleteLinkData = new DynamicDeleteLinkData();
                    dynamicDeleteLinkData.setUserName(userName);
                    dynamicDeleteLinkData.setDataId(dataId);
                    dynamicDeleteLinkData.setFormId(formId);
                    dynamicDeleteLinkData.setName(getTitle(businessType,paasFormEntityExt, finalExplainMap,
                            paasFormDataEntityExt));
                    dynamicDeleteLinkData.setCorpid(corpid);
                    dynamicDeleteLinkData.setUserId(userId);
                    dynamicDeleteLinkData.setParentDataId(parentDataId);
                    dynamicDeleteLinkData.setParentBusinessType(linkBusinessType);
                    dynamicDeleteLinkData.setDeletePaasFormData(paasFormDataEntityExt);
                    if(dataMap.containsKey(linkBusinessType)){
                        List<DynamicDeleteLinkData> list = dataMap.get(linkBusinessType);
                        list.add(dynamicDeleteLinkData);
                    }else{
                        List<DynamicDeleteLinkData> list = new ArrayList();
                        list.add(dynamicDeleteLinkData);
                        dataMap.put(linkBusinessType,list);
                    }
                }
            });
        }
        dataMap.forEach(( linkBusinessType,list)->{
            DynamicStrategy dynamicStrategy = dynamicStrategyFactory.getDynamicStrategyByBusinessType(linkBusinessType);
            dynamicStrategy.deleteBatchLinkData(list);
        });

    }

    //@Async("dynamicThreadPool")
    public void addLikData(LinkDataDynamicAddDTO linkDataDynamicAddDTO){
        SaasFormSaveDTO saasFormSaveDTO = new SaasFormSaveDTO();
        BeanUtil.copyProperties(linkDataDynamicAddDTO,saasFormSaveDTO);
        addLinkData(saasFormSaveDTO);
    }


    @Override
    public PaasFormDataEntityExt getFormData(String corpid, Integer saasMark, Integer businessType, Long dataId) throws XbbException {
        return formDataHelp.getFormData(corpid,saasMark, businessType, dataId);
    }

    @Async("dynamicThreadPool")
    public void addPushNotify(FormDataAddDTO formDataAddDTO,JSONObject oldDataList,Integer linkBusinessType){
        PushNotifyDynamicStrategy pushNotifyDynamicStrategy = dynamicStrategyFactory.getPushNotifyDynamicStrategy();
        DynamicPushNotifyAddDTO dynamicPushNotifyAddDTO = new DynamicPushNotifyAddDTO();
        dynamicPushNotifyAddDTO.setFormDataAddDTO(formDataAddDTO);
        dynamicPushNotifyAddDTO.setOldDataList(oldDataList);
        dynamicPushNotifyAddDTO.setLinkBusinessType(linkBusinessType);
        pushNotifyDynamicStrategy.addBatch(dynamicPushNotifyAddDTO);
    }

    @Async("dynamicThreadPool")
    public void changeStage(String corpid, Integer saasMark, Integer businessType, Long dataId,
                            String userId, Long formId,
                            PaasFormDataEntityExt paasFormDataEntityExt, CommonJumpDTO commonJumpDTO) throws XbbException {
        if(Objects.isNull(paasFormDataEntityExt)){
            paasFormDataEntityExt = formDataHelp.getFormData(corpid,saasMark,businessType,dataId);
        }
        PaasFormExplainEntity paasFormExplainEntity = proFormHelp.getExplainEntity(corpid, formId, businessType);
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
        String userName = commonJumpDTO.getLoginUserName();
        String fromStageName = "";
        if(Objects.isNull(commonJumpDTO.getFromStageEntity())){
            fromStageName = I18nMessageUtil.getMessage(StageTypeEnum.START_STAGE.getName());
        }else{
            fromStageName = commonJumpDTO.getFromStageEntity().getName();
        }
        String toStageName = commonJumpDTO.getToStageEntity().getName();
        Set<String> set = new HashSet<>();
        Set<Long> formIds =  new HashSet<>();
        JSONObject data = paasFormDataEntityExt.getData();
        explainMap.forEach((attr, fieldAttrEntity) -> {
            Integer fieldType = fieldAttrEntity.getFieldType();
            if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA.getType())) {
                LinkInfoPojo linkInfo = fieldAttrEntity.getLinkInfo();
                Integer linkBusinessType = linkInfo.getLinkBusinessType();
                if(!SHOW_DYNAMIC_BUSINESSTYPE_LIST.contains(linkBusinessType)){
                    return;
                }
                formIds.add(linkInfo.getLinkFormId());
            }
        });
        Map<String, Object> param = new HashMap<>(2 << 1);
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        param.put(ParameterConstant.ID_IN, formIds);
        List<PaasFormEntity> paasFormEntityList = paasFormModel.findEntity(param);
        Map<Long,Set<String>> associationMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        paasFormEntityList.forEach(item->{
            PaasFormEntity paasFormEntity = item;
            List<LinkListPojo> associationList = JSONArray.parseArray(paasFormEntity.getAssociationList(), LinkListPojo.class);
            if (Objects.isNull(associationList)) {
                associationList = new ArrayList<>();
            }
            Set<String> associationSet = new HashSet<>();
            associationList.forEach(temp->{
                Integer linkSaasMark = temp.getLinkSaasMark();
                Integer linkBusinessType = temp.getLinkBusinessType();
                if (Objects.equals(temp.getEnable(), 1)) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(linkSaasMark).append(linkBusinessType).append(formId);
                    associationSet.add(sb.toString());
                }
            });
            associationMap.put(item.getId(),associationSet);
        });
        Map<Integer,List<DynamicLinkDataStageJump>> dataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        AnalysisDataDTO analysisDataDTO = new AnalysisDataDTO();
        BeanUtil.copyProperties(commonJumpDTO,analysisDataDTO);
        PaasFormDataEntityExt finalPaasFormDataEntityExt = paasFormDataEntityExt;
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formId,corpid);
        String finalFromStageName = fromStageName;
        explainMap.forEach((attr, fieldAttrEntity)->{
                Integer fieldType = fieldAttrEntity.getFieldType();
                if(Objects.equals(fieldType, FieldTypeEnum.LINK_DATA.getType())){
                    LinkInfoPojo linkInfo = fieldAttrEntity.getLinkInfo();
                    Integer linkSaasMark = linkInfo.getLinkSaasMark();
                    Integer linkBusinessType = linkInfo.getLinkBusinessType();
                    Long linkFormId = linkInfo.getLinkFormId();
                    if(!SHOW_DYNAMIC_BUSINESSTYPE_LIST.contains(linkBusinessType)){
                        return;
                    }
                    StringBuilder key = new StringBuilder();
                    Long parentDataId = data.getLong(attr);
                    key.append(linkSaasMark).append(linkBusinessType).append(parentDataId).append(dataId);
                    StringBuilder sb = new StringBuilder();
                    sb.append(saasMark).append(businessType).append(finalPaasFormDataEntityExt.getFormId());
                    Set<String> tempSet = associationMap.get(linkFormId);
                    if(!tempSet.contains(sb.toString())){
                        return;
                    }
                    if(set.contains(key.toString())){
                        return;
                    }else {
                        set.add(key.toString());
                    }
                    DynamicLinkDataStageJump dynamicLinkDataStageJump = new DynamicLinkDataStageJump();
                    dynamicLinkDataStageJump.setUserName(userName);
                    dynamicLinkDataStageJump.setDataId(dataId);
                    dynamicLinkDataStageJump.setFormId(formId);
                    dynamicLinkDataStageJump.setName(getTitle(businessType,paasFormEntityExt, explainMap,
                            finalPaasFormDataEntityExt));
                    dynamicLinkDataStageJump.setCorpid(corpid);
                    dynamicLinkDataStageJump.setUserId(userId);
                    dynamicLinkDataStageJump.setParentDataId(parentDataId);
                    dynamicLinkDataStageJump.setParentBusinessType(linkBusinessType);
                    dynamicLinkDataStageJump.setFromStageName(finalFromStageName);
                    dynamicLinkDataStageJump.setToStageName(toStageName);
                    dynamicLinkDataStageJump.setBusinessType(businessType);
                    if(dataMap.containsKey(linkBusinessType)){
                        List<DynamicLinkDataStageJump> list = dataMap.get(linkBusinessType);
                        list.add(dynamicLinkDataStageJump);
                    }else{
                        List<DynamicLinkDataStageJump> list = new ArrayList();
                        list.add(dynamicLinkDataStageJump);
                        dataMap.put(linkBusinessType,list);
                    }
                }
            });

        dataMap.forEach(( linkBusinessType,list)->{
            DynamicStrategy dynamicStrategy = dynamicStrategyFactory.getDynamicStrategyByBusinessType(linkBusinessType);
            dynamicStrategy.linkDataStageJump(list);
        });
    }

    /**
     * 动态获取title
     * date: 2022/6/21 9:52 上午
     * @author yingjf
     * @param businessType:
     * @param paasFormEntityExt:
     * @param explainMap:
     * @param paasFormDataEntityExt:
     */
    private String getTitle(Integer businessType,PaasFormEntityExt paasFormEntityExt,Map<String, FieldAttrEntity> explainMap,
                            PaasFormDataEntityExt paasFormDataEntityExt){

        return TitleUtil.getTitle(businessType, paasFormEntityExt, explainMap, paasFormDataEntityExt);
    }

    /**
     * 重新获取引用名称，防止关联对象名称更改
     * @param corpid
     * @param refId
     * @param businessType
     * @param refName
     * @return
     */
    public String getRealRefName(String corpid,Long refId,Integer businessType,String refName){
        try {
            XbbRefTypeEnum refTypeEnum = XbbRefTypeEnum.getByCode(businessType);
            switch (refTypeEnum){
                case COMPETITOR:
                    CompetitorEntity competitor = competitorModel.getByKey(refId, corpid);
                    refName = FastJsonHelper.getStringOrDefault(competitor.getData(), CompetitorEnum.NAME.getAttr(),"");
                    break;
                case SALES_OPPORTUNITY:
                    OpportunityEntityExt opportunityEntityExt = opportunityModel.getByKey(refId, corpid);
                    refName = FastJsonHelper.getStringOrDefault(opportunityEntityExt.getData(), SalesOpportunityEnum.NAME.getAttr(), "");
                    break;
                default:
                    refName = refName;
            }
        }catch (Exception e){
            log.error("com.xbongbong.paas.service.dynamic.help.DynamicHelp.getRealRefName", e);
        }
        return refName;
    }

    /**
     * 根据业务类型获取模版名称
     *
     * 如果是多模版，展示模版名称
     * 如果是单模版，展示业务的菜单名称
     * @param businessType
     * @param saasMark
     * @param corpid
     * @return
     */
    public String getTemplateName(Integer businessType,Long refId,Integer saasMark,String corpid) {
        try {
            RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(businessType);
            if (Objects.equals(redundantTemplateTypeEnum,RedundantTemplateTypeEnum.UNKNOWN)){
                return XbbRefTypeEnum.getByCode(businessType).getName();
            }
            PaasFormDataEntityExt paasFormDataEntityExt = proGetHelp.getByKey(refId, businessType, saasMark, corpid);
            Long formId = paasFormDataEntityExt.getFormId();
            PaasFormEntityExt paasForm = paasFormModel.getByKey(formId, corpid);
            return paasForm.getName();
        }catch (Exception e){
            log.error("com.xbongbong.paas.service.dynamic.help.DynamicHelp.getTemplateName exception:",e);
            return XbbRefTypeEnum.getByCode(businessType).getName();
        }
    }


}
